//
//  NSObject+Util.m
//  wozhua
//
//  Created by 王洋 on 14/11/27.
//  Copyright (c) 2014年 王洋. All rights reserved.
//

#import "NSObject+Util.h"

@implementation NSObject (Util)

+ (void)swizzleMethod:(SEL)selectorA toMethod:(SEL)selectorB {
    Method originalMethodImp = class_getInstanceMethod([self class], selectorA);
    Method destMethodImp = class_getInstanceMethod([self class], selectorB);
    
    if (class_addMethod([self class], selectorA, method_getImplementation(destMethodImp), method_getTypeEncoding(originalMethodImp))) {
        //要替换的方法没有实现
        class_replaceMethod([self class],
                            selectorA,
                            method_getImplementation(originalMethodImp),
                            method_getTypeEncoding(originalMethodImp));
    } else {
        method_exchangeImplementations(originalMethodImp, destMethodImp);
    }
}

+ (id)performClassMethod:(SEL)aSelector withObject:(id)anArgument {
    Class aClass = [self class];
    
    //初始化NSMethodSignature对象
    NSMethodSignature *sig = [aClass methodSignatureForSelector:aSelector];
    
    //初始化NSInvocation对象
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
    
    //设置执行目标对象
    [invocation setTarget:aClass];
    
    //设置执行的selector
    [invocation setSelector:aSelector];
    
    //设置参数
    if (anArgument) {
        [invocation setArgument:&anArgument atIndex:2];
    }
    
    //执行方法
    [invocation retainArguments];
    [invocation invoke];
    
    id __unsafe_unretained result = nil;
    //获取返回值
    [invocation getReturnValue:&result];
    
    return result;
}

- (void)performBlock:(void (^)(void))block afterDelay:(NSTimeInterval)delay {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), block);
}

- (void)performBlockInBackground:(void (^)(void))block {
    dispatch_async(dispatch_get_global_queue(0, 0), block);
}

- (void)performBlockOnMainThread:(void (^)(void))block {
    if ([NSThread isMainThread]) {
        block();
    } else {
        dispatch_async(dispatch_get_main_queue(), block);
    }
}

- (NSString *)getSelfMemoryAddress {
    NSString *memoryAddress = [NSString stringWithFormat:@"%X", (unsigned int) self];
    return memoryAddress;
}

@end
